<template>
  <Teleport to="body">
    <Transition name="dialog-fade" appear>
      <div v-if="visible" :class="overlayClasses" @click="handleOverlayClick">
        <Transition name="dialog-zoom" appear>
          <div v-if="visible" :class="dialogClasses" @click.stop>
            <!-- 对话框头部 -->
            <div v-if="showHeader" :class="headerClasses">
              <div class="base-dialog__title-wrapper">
                <el-icon v-if="icon" class="base-dialog__icon">
                  <User v-if="icon === 'User'" />
                  <Edit v-else-if="icon === 'Edit'" />
                  <Lock v-else-if="icon === 'Lock'" />
                  <DocumentAdd v-else-if="icon === 'DocumentAdd'" />
                  <component :is="icon" v-else />
                </el-icon>
                <h3 class="base-dialog__title">
                  <slot name="title">{{ title }}</slot>
                </h3>
              </div>
              
              <button
                v-if="showClose"
                type="button"
                class="base-dialog__close"
                @click="handleClose"
              >
                <el-icon><Close /></el-icon>
              </button>
            </div>

            <!-- 对话框内容 -->
            <div :class="bodyClasses">
              <slot />
            </div>

            <!-- 对话框底部 -->
            <div v-if="showFooter" :class="footerClasses">
              <slot name="footer">
                <div class="base-dialog__actions">
                  <BaseButton
                    v-if="showCancelButton"
                    :size="buttonSize"
                    variant="outline"
                    @click="handleCancel"
                  >
                    {{ cancelButtonText }}
                  </BaseButton>
                  <BaseButton
                    v-if="showConfirmButton"
                    :size="buttonSize"
                    :type="confirmButtonType"
                    :loading="confirmLoading"
                    @click="handleConfirm"
                  >
                    {{ confirmButtonText }}
                  </BaseButton>
                </div>
              </slot>
            </div>
          </div>
        </Transition>
      </div>
    </Transition>
  </Teleport>
</template>

<script setup>
import { computed, watch, nextTick } from 'vue'
import { Close, User, Edit, Lock, DocumentAdd } from '@element-plus/icons-vue'
import BaseButton from './BaseButton.vue'

const props = defineProps({
  // 是否显示
  visible: {
    type: Boolean,
    default: false
  },
  // 标题
  title: {
    type: String,
    default: ''
  },
  // 图标
  icon: {
    type: [String, Object],
    default: null
  },
  // 宽度
  width: {
    type: [String, Number],
    default: '600px'
  },
  // 最大宽度
  maxWidth: {
    type: [String, Number],
    default: '90vw'
  },
  // 最大高度
  maxHeight: {
    type: [String, Number],
    default: '80vh'
  },
  // 是否显示头部
  showHeader: {
    type: Boolean,
    default: true
  },
  // 是否显示底部
  showFooter: {
    type: Boolean,
    default: true
  },
  // 是否显示关闭按钮
  showClose: {
    type: Boolean,
    default: true
  },
  // 是否显示取消按钮
  showCancelButton: {
    type: Boolean,
    default: true
  },
  // 是否显示确认按钮
  showConfirmButton: {
    type: Boolean,
    default: true
  },
  // 取消按钮文本
  cancelButtonText: {
    type: String,
    default: '取消'
  },
  // 确认按钮文本
  confirmButtonText: {
    type: String,
    default: '确认'
  },
  // 确认按钮类型
  confirmButtonType: {
    type: String,
    default: 'primary'
  },
  // 确认按钮加载状态
  confirmLoading: {
    type: Boolean,
    default: false
  },
  // 按钮大小
  buttonSize: {
    type: String,
    default: 'medium'
  },
  // 是否可以通过点击遮罩关闭
  closeOnClickModal: {
    type: Boolean,
    default: true
  },
  // 是否可以通过ESC关闭
  closeOnPressEscape: {
    type: Boolean,
    default: true
  },
  // 是否在关闭前确认
  beforeClose: {
    type: Function,
    default: null
  },
  // 是否居中显示
  center: {
    type: Boolean,
    default: true
  },
  // 是否全屏
  fullscreen: {
    type: Boolean,
    default: false
  },
  // 是否可拖拽
  draggable: {
    type: Boolean,
    default: false
  },
  // 层级
  zIndex: {
    type: Number,
    default: 1000
  }
})

const emit = defineEmits(['update:visible', 'close', 'cancel', 'confirm', 'open', 'opened', 'closed'])

// 计算样式类名
const overlayClasses = computed(() => {
  const classes = ['base-dialog-overlay']
  
  if (props.center) classes.push('base-dialog-overlay--center')
  
  return classes
})

const dialogClasses = computed(() => {
  const classes = ['base-dialog']
  
  if (props.fullscreen) classes.push('base-dialog--fullscreen')
  if (props.draggable) classes.push('base-dialog--draggable')
  
  return classes
})

const headerClasses = computed(() => {
  const classes = ['base-dialog__header']
  
  if (props.icon) classes.push('base-dialog__header--with-icon')
  
  return classes
})

const bodyClasses = computed(() => {
  const classes = ['base-dialog__body']
  
  if (!props.showHeader) classes.push('base-dialog__body--no-header')
  if (!props.showFooter) classes.push('base-dialog__body--no-footer')
  
  return classes
})

const footerClasses = computed(() => {
  return ['base-dialog__footer']
})

// 对话框样式
const dialogStyle = computed(() => {
  const style = {
    zIndex: props.zIndex
  }
  
  if (!props.fullscreen) {
    style.width = typeof props.width === 'number' ? `${props.width}px` : props.width
    style.maxWidth = typeof props.maxWidth === 'number' ? `${props.maxWidth}px` : props.maxWidth
    style.maxHeight = typeof props.maxHeight === 'number' ? `${props.maxHeight}px` : props.maxHeight
  }
  
  return style
})

// 事件处理
const handleOverlayClick = () => {
  if (props.closeOnClickModal) {
    handleClose()
  }
}

const handleClose = async () => {
  if (props.beforeClose) {
    const shouldClose = await props.beforeClose()
    if (!shouldClose) return
  }
  
  emit('update:visible', false)
  emit('close')
}

const handleCancel = () => {
  emit('cancel')
  handleClose()
}

const handleConfirm = () => {
  emit('confirm')
}

const handleEscapeKey = (event) => {
  if (event.key === 'Escape' && props.closeOnPressEscape && props.visible) {
    handleClose()
  }
}

// 监听键盘事件
watch(() => props.visible, (newVal) => {
  if (newVal) {
    document.addEventListener('keydown', handleEscapeKey)
    document.body.style.overflow = 'hidden'
    emit('open')
    nextTick(() => {
      emit('opened')
    })
  } else {
    document.removeEventListener('keydown', handleEscapeKey)
    document.body.style.overflow = ''
    emit('closed')
  }
}, { immediate: true })

// 组件卸载时清理
import { onUnmounted } from 'vue'
onUnmounted(() => {
  document.removeEventListener('keydown', handleEscapeKey)
  document.body.style.overflow = ''
})
</script>

<style scoped>
.base-dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: var(--color-bg-overlay);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: var(--spacing-xl) var(--spacing-lg);
  overflow-y: auto;
  z-index: var(--z-modal);
  /* 确保滚动条样式 */
  scrollbar-width: thin;
  scrollbar-color: var(--color-gray-400) transparent;
}

.base-dialog-overlay::-webkit-scrollbar {
  width: 6px;
}

.base-dialog-overlay::-webkit-scrollbar-track {
  background: transparent;
}

.base-dialog-overlay::-webkit-scrollbar-thumb {
  background: var(--color-gray-400);
  border-radius: 3px;
}

.base-dialog-overlay--center {
  align-items: center;
}

.base-dialog {
  background: #ffffff;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
  display: flex;
  flex-direction: column;
  max-height: 80vh;
  min-height: 200px;
  overflow: hidden;
  position: relative;
  transform-origin: center;
  margin: 15vh auto 50px;
}

.base-dialog--fullscreen {
  width: 100vw !important;
  height: 100vh !important;
  max-width: none !important;
  max-height: none !important;
  border-radius: 0;
  margin: 0;
}

.base-dialog__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 20px 0;
  border-bottom: none;
  background: var(--color-bg-primary);
  color: var(--color-text-primary);
}

.base-dialog__title-wrapper {
  display: flex;
  align-items: center;
  gap: var(--spacing-md);
  flex: 1;
  min-width: 0;
}

.base-dialog__icon {
  font-size: var(--font-size-xl);
  flex-shrink: 0;
}

.base-dialog__title {
  font-size: 18px;
  font-weight: 500;
  margin: 0;
  color: #303133;
  line-height: 24px;
}

.base-dialog__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  padding: 0;
  margin: 0;
  color: #909399;
  background: transparent;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  transition: var(--transition-fast);
  flex-shrink: 0;
  font-size: 16px;
}

.base-dialog__close:hover {
  color: #409eff;
  background: #f5f7fa;
}

.base-dialog__body {
  flex: 1;
  padding: 20px;
  overflow-y: auto;
  min-height: 0;
  max-height: calc(80vh - 120px);
  color: #606266;
  font-size: 14px;
  line-height: 1.5;
}

.base-dialog__body::-webkit-scrollbar {
  width: 6px;
}

.base-dialog__body::-webkit-scrollbar-track {
  background: var(--color-gray-100);
  border-radius: 3px;
}

.base-dialog__body::-webkit-scrollbar-thumb {
  background: var(--color-gray-300);
  border-radius: 3px;
}

.base-dialog__body::-webkit-scrollbar-thumb:hover {
  background: var(--color-gray-400);
}

.base-dialog__body--no-header {
  padding-top: var(--spacing-2xl);
  max-height: calc(85vh - 80px);
}

.base-dialog__body--no-footer {
  padding-bottom: var(--spacing-2xl);
  max-height: calc(85vh - 80px);
}

.base-dialog__footer {
  flex-shrink: 0;
  padding: 10px 20px 20px;
  border-top: none;
  background: var(--color-bg-primary);
  text-align: right;
}

.base-dialog__actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

/* 动画效果 */
.dialog-fade-enter-active,
.dialog-fade-leave-active {
  transition: opacity var(--transition-normal);
}

.dialog-fade-enter-from,
.dialog-fade-leave-to {
  opacity: 0;
}

.dialog-zoom-enter-active,
.dialog-zoom-leave-active {
  transition: all var(--transition-normal);
}

.dialog-zoom-enter-from,
.dialog-zoom-leave-to {
  opacity: 0;
  transform: scale(0.9) translateY(-20px);
}

/* 响应式设计 */
@media (max-width: 768px) {
  .base-dialog-overlay {
    padding: 10px;
    align-items: flex-start;
  }

  .base-dialog {
    width: calc(100% - 20px) !important;
    max-width: none !important;
    max-height: 90vh !important;
    margin: 50px auto;
  }

  .base-dialog__header {
    padding: 15px 15px 0;
  }

  .base-dialog__body {
    padding: 15px;
    max-height: calc(90vh - 120px);
  }

  .base-dialog__footer {
    padding: 10px 15px 15px;
  }

  .base-dialog__actions {
    flex-direction: column-reverse;
    gap: 10px;
  }

  .base-dialog__actions .base-button {
    width: 100%;
  }
}

@media (max-width: 480px) {
  .base-dialog-overlay {
    padding: var(--spacing-sm);
  }

  .base-dialog {
    max-height: 98vh !important;
    margin: var(--spacing-xs) 0;
  }

  .base-dialog__header {
    padding: var(--spacing-md) var(--spacing-md) var(--spacing-sm);
  }

  .base-dialog__title {
    font-size: var(--font-size-lg);
  }

  .base-dialog__body {
    padding: var(--spacing-sm) var(--spacing-md);
    max-height: calc(98vh - 120px);
  }

  .base-dialog__footer {
    padding: var(--spacing-sm) var(--spacing-md);
  }
}

/* 横屏模式优化 */
@media (max-height: 600px) and (orientation: landscape) {
  .base-dialog {
    max-height: 90vh !important;
  }

  .base-dialog__body {
    max-height: calc(90vh - 100px);
  }

  .base-dialog__header {
    padding: var(--spacing-md) var(--spacing-2xl) var(--spacing-sm);
  }

  .base-dialog__footer {
    padding: var(--spacing-sm) var(--spacing-2xl);
  }
}
</style>
